package com.sixth.controller;

import com.sixth.annotation.OperationLogAdvice;
import com.sixth.bean.MarketAdmin;
import com.sixth.bean.common.*;
import com.sixth.constant.Constant;
import com.sixth.service.AdminAuthService;
import com.sixth.service.AdminRoleService;
import com.sixth.shiro.MarketToken;
import com.sixth.util.EncryptionUtil;
import com.sixth.util.MarketInfoUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;

//shiro整合之后，在做具体的开发
//响应结果都是JSON，Controller组件上我们都用@RestController注解
@RestController
@RequestMapping("admin/auth")
public class AuthController {

    @Autowired
    AdminRoleService adminRoleService;

    @Autowired
    AdminAuthService adminAuthService;
    /**
     * Shiro安全框架 → 视频课程 4个课时 → 认证（登录）
     * 如果参数比较少，类型比较简单的话，使用map来接收也可以
     */
    @OperationLogAdvice(operation = "登录", operationType = 1)
    @PostMapping("login")
    public BaseRespVo login(@RequestBody Map map, HttpServletRequest request) {
        String username = (String) map.get("username");

        String password = (String) map.get("password");

        //String password1 = EncryptionUtil.getMD5String((String) map.get("password"),username);
        Subject subject = SecurityUtils.getSubject();

        // 设置session存活时间120min
        HttpSession session = request.getSession();
        session.setMaxInactiveInterval(120 * 60);
        // 登录，先进行认证，再进行授权
        try {
            subject.login(new MarketToken(username, password, Constant.ADMIN_LOGIN));
        }catch (Exception e) {
            return BaseRespVo.noLogin();
        }

        MarketAdmin marketAdmin = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();

        // 维护管理员上次登录时间和ip
        adminAuthService.updateLastLoginIpAndTime(marketAdmin,request.getRemoteAddr());

        LoginUserData loginUserData = new LoginUserData();

        AdminInfoBean adminInfo = new AdminInfoBean();
        adminInfo.setAvatar(marketAdmin.getAvatar());
        adminInfo.setNickName(marketAdmin.getUsername());
        loginUserData.setAdminInfo(adminInfo);


        // 获取sessionId
        loginUserData.setToken((String) subject.getSession().getId());
        return BaseRespVo.ok(loginUserData);


    }


    @RequestMapping("info")
    public BaseRespVo info(String token) {


        //开发完shiro之后，再整合
        MarketAdmin marketAdmin = MarketInfoUtil.getMarketAdmin();

        if (marketAdmin == null) {
            return BaseRespVo.unAuthc();
        }
        InfoData infoData = new InfoData();
        //infoData.setName("admin123");
        infoData.setName(marketAdmin.getUsername());

        //根据primaryPrincipal做查询
        //infoData.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        infoData.setAvatar(marketAdmin.getAvatar());

        Subject subject = SecurityUtils.getSubject();

        // TODO 这两个信息再从数据库中查一遍？
        Integer[] roleIds = marketAdmin.getRoleIds();
        List<String> roles = adminRoleService.getRolesName(roleIds);

        // ArrayList<String> roles = new ArrayList<>();
        // roles.add("超级管理员");
        infoData.setRoles(roles);


        List<String> permissions = adminRoleService.getPermissionApi(roleIds);

        infoData.setPerms(permissions);

        return BaseRespVo.ok(infoData);
    }


    /**
     * 认证失败后的处理
     *
     * @Param
     * @Return
     * @author XiaoWJ
     * @date 2022/9/9 15:20
     */

    @OperationLogAdvice(operation = "登录", operationType = 1)
    @RequestMapping("noAuthc")
    public BaseRespVo noAuthc() {
        // 认证失败
        return BaseRespVo.invalidData("用户名或密码错误");
    }


    //@RequiresPermissions(value = {"admin:auth:logout"},logical = Logical.OR)
    @OperationLogAdvice(operation = "退出登录", operationType = 1)
    @RequestMapping("logout")
    public BaseResultVo logout() {
        // 认证失败
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection principals = subject.getPrincipals();
        Object primaryPrincipal = principals.getPrimaryPrincipal();
        subject.logout();

        return BaseResultVo.ok();
    }


}




